package com.hframe.taglib.json;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;

public class JsonBaseTag extends TagSupport {
	private static final long serialVersionUID = 1L;
	protected JsonElement obJson = null;

	protected boolean out = false;
	protected String json = null;
	protected String key = null;
	protected int superior = 0;
	protected String defaults;
	protected String outVar = null;
	protected boolean empty = false;
	protected boolean ifNull = true;

	public boolean isEmpty() {
		return empty;
	}

	public void setEmpty(boolean empty) {
		this.empty = empty;
	}

	public boolean isIfNull() {
		return ifNull;
	}

	public void setIfNull(boolean ifNull) {
		this.ifNull = ifNull;
	}

	@Override
	public void setParent(Tag t) {
		super.setParent(t);
		obJson = new JsonObject();
		out = false;
		json = null;
		key = null;
		defaults = "";
		empty = false;
		ifNull = false;
	}

	public String getOutVar() {
		return outVar;
	}

	public void setOutVar(String outVar) {
		this.outVar = outVar;
	}

	public String getDefaults() {
		return defaults;
	}

	public void setDefaults(String defaults) {
		this.defaults = defaults;
	}

	public int getSuperior() {
		return superior;
	}

	public void setSuperior(int superior) {
		this.superior = superior;
	}

	public String getJson() {
		return json;
	}

	@Override
	public int doStartTag() throws JspException {
		if (!empty)
			if (ifNull)
				empty = this.json == null || "".equals(this.json);

		if (empty)
			return Tag.SKIP_BODY;

		return Tag.EVAL_BODY_INCLUDE;
	}

	public void setJson(String json) {
		this.json = json;
	}

	@Override
	public int doEndTag() throws JspException {
		return Tag.EVAL_PAGE;
	}

	public String getKey() {
		return this.key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public boolean isOut() {
		return out;
	}

	public void setOut(boolean out) {
		this.out = out;
	}

	protected void outJson() throws JspException {
		try {
			if (this.json != null) {
				if (this.out)
					pageContext.getOut().write(this.json);
				if (this.outVar != null)
					pageContext.getSession().setAttribute(this.outVar, this.json);
			} else {
				if (this.out)
					pageContext.getOut().write(this.defaults);
				if (this.outVar != null)
					pageContext.getSession().setAttribute(this.outVar, this.defaults);
			}
		} catch (IOException e) {
			throw new JspException(e.getMessage());
		}
	}

	@Override
	public JsonBaseTag getParent() {
		Tag tag = super.getParent();
		int parent = this.superior;
		while (tag != null) {
			if (tag instanceof JsonBaseTag) {
				if (parent == 0)
					return (JsonBaseTag) tag;
				parent--;
			}
			tag = tag.getParent();
		}
		return null;
	}

	protected void GetJson() {
		if (null == this.obJson)
			return;

		if (null == this.key || "".equals(this.key))
			return;

		String[] keys = this.key.split("\\.");
		for (String ikey : keys) {
			if (this.obJson instanceof JsonObject) {
				this.obJson = this.obJson.getAsJsonObject().get(ikey);
			} else {
				this.obJson = null;
				break;
			}
		}

		if (this.obJson != null)
			if (this.obJson.isJsonObject() || this.obJson.isJsonArray())
				this.json = this.obJson.toString();
			else if (this.obJson instanceof JsonPrimitive)
				this.json = this.obJson.getAsString();
	}

	protected JsonElement getObJson() {
		return obJson;
	}

	protected void setObJson(JsonElement obJson) {
		this.obJson = obJson;
	}

}
